<template>
  <div class="tw-libswiper xfb3d">
    <div ref="contentBox" class="tw-libswiper-slots">
      <slot>
      </slot>
    </div>

    <div v-if="type==='content' && childNumber===0" class="tw-libswiper-slots-placeholder">请将组件拖入到此处</div>

    <div :id="`swiper${_uid}`" class="swiper-container">
      <div class="swiper-wrapper">
        <template v-if="type === 'content'">
          <div :id="_uid+'slide'+idx" class="swiper-slide" :class="{xright3d: activeIndex + parseInt(slidesPerView) === idx}" v-for="idx in childNumber" :key="idx"></div>
        </template>
        <div v-else-if="type === 'text'"
          class="swiper-slide"
          v-for="(item, idx) in textListResult"
          :key="idx">
          <a
            class="tw-libswiper-textbox"
            v-if="item.title"
            :href="item.href"
            :target="item.target || '_self'">
              <i class="tw-libswiper-item-dot"
                  v-if="hasBeforeDot"
                  :class="{'xcircle': dotType === 'circle', 'xring': dotType === 'ring'}">
              </i>
              <span class="tw-libswiper-item-tit"
                  :class="{'xellipsis': titleEllipsis}"
                  :title="item.title">{{item.title}}</span>

              <span v-if="hasDate"
                class="tw-libswiper-item-date">{{item.date}}</span>
          </a>
        </div>
        <div v-else
          class="swiper-slide"
          :class="{xright3d: activeIndex + parseInt(slidesPerView) === idx}"
          v-for="(img, idx) in imageListResult"
          :key="idx">
          <a v-if="img.href"
            class="tw-libswiper-imgbox"
            :href="img.href"
            :style="{backgroundColor: img.backgroundColor}"
            :target="img.target || '_self'">
            <img class="tw-libswiper-img" :style="{objectFit: imageFillType}" :src="img.url" />
            <div v-if="imageTitleVisibal" class="tw-libswiper-imgtitle">{{img.title}}</div>
          </a>
          <div v-else class="tw-libswiper-imgbox" :style="{backgroundColor: img.backgroundColor}">
            <img class="tw-libswiper-img" :style="{objectFit: imageFillType}" :src="img.url" />
            <div v-if="imageTitleVisibal" class="tw-libswiper-imgtitle">{{img.title}}</div>
          </div>
        </div>
      </div>

      <!-- 如果需要分页器 -->
      <div v-if="paginationEnable" class="swiper-pagination" :class="['x'+paginationMarkType]"></div>

      <!-- 如果需要导航按钮 -->
      <template v-if="buttonEnable && !buttonOUtEnable">
        <div v-if="prevIcon && prevIcon.length>0" class="swiper-button-prev"  :id="`swiper-button-prev${_uid}`" :style="{height: iconSize, backgroundImage: `url('${$twApp.fileBaseUrl}${prevIcon[0].localPath}')`, backgroundSize: `auto ${iconSize}`}"></div>
        <div v-else class="swiper-button-prev" :id="`swiper-button-prev${_uid}`"></div>
        <div v-if="nextIcon && nextIcon.length>0" class="swiper-button-next" :id="`swiper-button-next${_uid}`" :style="{height: iconSize, backgroundImage: `url('${$twApp.fileBaseUrl}${nextIcon[0].localPath}')`, backgroundSize: `auto ${iconSize}`}"></div>
        <div v-else class="swiper-button-next" :id="`swiper-button-next${_uid}`"></div>
      </template>

      <!-- 如果需要滚动条 -->
      <!-- <div class="swiper-scrollbar"></div> -->
  </div>

  <!-- 如果需要导航按钮且在外面显示 -->
  <template v-if="buttonEnable && buttonOUtEnable">
    <div v-if="prevIcon && prevIcon.length>0" class="swiper-button-prev"  :id="`swiper-button-prev${_uid}`" :style="{height: iconSize, backgroundImage: `url('${$twApp.fileBaseUrl}${prevIcon[0].localPath}')`, backgroundSize: `auto ${iconSize}`}"></div>
    <div v-else class="swiper-button-prev" :id="`swiper-button-prev${_uid}`"></div>
    <div v-if="nextIcon && nextIcon.length>0" class="swiper-button-next" :id="`swiper-button-next${_uid}`" :style="{height: iconSize, backgroundImage: `url('${$twApp.fileBaseUrl}${nextIcon[0].localPath}')`, backgroundSize: `auto ${iconSize}`}"></div>
    <div v-else class="swiper-button-next" :id="`swiper-button-next${_uid}`"></div>
  </template>

</div>
</template>

<script>
import props from './props'
import Swiper from 'swiper/bundle'
import 'swiper/swiper-bundle.css'
import style from '../tw-lib-base/style'
import bannerMixins from '../tw-lib-base/banner-document/mixins'

export default {
  name: 'tw-libswiper',

  props,

  mixins: [style, bannerMixins],

  data() {
    return {
      swiper: null,
      len: 0,
      childNumber: 0,
      activeIndex: 0,
      observer: null
    }
  },

  computed: {
    imageListResult () {
      const result = this.imageListFromApi.length > 0 ? this.imageListFromApi : this.imageListFromProp
      return result.map(img => {
        img.url = this.$ui.genImagePath(img.localPath || img.url)
        return img
      })
    },
    textListResult () {
      const result = this.textListFromApi.length > 0 ? this.textListFromApi : this.textListFromProp
      return result
    },

    swiperConfig () {
      return {
        type: this.type,
        loop: this.loop,
        direction: this.direction,
        initialSlide: this.initialSlide,
        slidesPerView: this.slidesPerView,
        imageTitleVisibal: this.imageTitleVisibal,
        imageTitleHeight: this.imageTitleHeight,
        imageTitleBg: this.imageTitleBg,
        imageTitleColor: this.imageTitleColor,
        imageTitleFontSize: this.imageTitleFontSize,
        paginationEnable: this.paginationEnable,
        buttonEnable: this.buttonEnable,
        mousewheel: this.wheelEnable,
        imageFillType: this.imageFillType,
        autoplay: this.autoplay,
        autoplayTime: this.autoplayTime,
        disableOnInteraction: this.disableOnInteraction,
        speed: this.speed
      }
    },

    style () {
      return {
        paginationMarkSize: this.paginationMarkSize,
        paginationMarColor: this.paginationMarColor,
        paginationMarActiveColor: this.paginationMarActiveColor,
        enableSide3d: this.enableSide3d,
        perspective: this.perspective,
        rotateY: this.rotateY,
        translateX: this.translateX,
        scale: this.scale,
        iconWidth: this.iconWidth
      }
    },

    needPseudoElement () {
      return parseInt(this.slidesPerView) > 1 && this.enableSide3d
    }
  },

  methods: {
    handleMutation (val) {
      if (!this.observer) {
        const vm = this

        this.observer = new MutationObserver((mutationsList, observer) => {
          for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
              vm.init()
            }
          }
        })
      }

      if (val) {
        this.observer.observe(this.$refs.contentBox, { childList: true })
      } else {
        this.observer.disconnect()
      }
    },

    setStyle () {
      let style = `
        ::root .swiper-pagination-bullet {
          width: ${this.paginationMarkSize};
          height: ${this.paginationMarkSize};
          background: ${this.paginationMarColor};
        }

        ::root .swiper-pagination-bullet-active {
          background: ${this.paginationMarActiveColor};
        }

        ::root .xcircle .swiper-pagination-bullet {
          border: 2px solid ${this.paginationMarColor};
        }

        ::root .xcircle .swiper-pagination-bullet-active {
          border: 2px solid ${this.paginationMarActiveColor};
          background: ${this.paginationMarActiveColor};
        }

        ::root .swiper-button-prev,
        ::root .swiper-button-next {
          width: ${this.iconWidth}
        }
      `
      const perspective = this.perspective || 0
      const rotateY = this.rotateY || 0
      const translateX = this.translateX || 0
      const scale = this.scale || 0

      if (this.needPseudoElement) {
        style += `
          ::root .swiper-slide-active {
            -moz-transform: perspective(${perspective}) rotateY(-${rotateY}deg) translateX(${translateX}) scale(${scale});
            -webkit-transform: perspective(${perspective}) rotateY(-${rotateY}deg) translateX(${translateX}) scale(${scale});
            transform: perspective(${perspective}) rotateY(-${rotateY}deg) translateX(${translateX}) scale(${scale});
          }

          ::root .swiper-slide.xright3d {
            -moz-transform: perspective(${perspective}) rotateY(${rotateY}deg) translateX(-${translateX}) scale(${scale});
            -webkit-transform: perspective(${perspective}) rotateY(${rotateY}deg) translateX(-${translateX}) scale(${scale});
            transform: perspective(${perspective}) rotateY(${rotateY}deg) translateX(-${translateX}) scale(${scale});
          }
        `
      }

      if (this.imageTitleVisibal) {
        if (this.imageTitleHeight) {
          style += `
            ::root .tw-libswiper-imgtitle {
              height: ${this.imageTitleHeight};
            }
          `
        }

        if (this.imageTitleBg) {
          style += `
            ::root .tw-libswiper-imgtitle {
              background: ${this.imageTitleBg};
            }
          `
        }

        if (this.imageTitleColor) {
          style += `
            ::root .tw-libswiper-imgtitle {
              color: ${this.imageTitleColor};
            }
          `
        }

        if (this.imageTitleFontSize) {
          style += `
            ::root .tw-libswiper-imgtitle {
              font-size: ${this.imageTitleFontSize};
            }
          `
        }

        if (this.type.options.value === 'text') {
          style += `
              ::root .tw-libswiper-textbox .tw-libswiper-item-dot {
              width: ${this.dotSize};
              height: ${this.dotSize};
              color: ${this.dotColor};
            }

            ::root .tw-libswiper-textbox .tw-libswiper-item-dot:hover {
              color: ${this.dotHoverColor}
            }


            ::root .tw-libswiper-textbox .tw-libswiper-item-tit {
              color: ${this.titleColor};
              font-size: ${this.titleFontSize};
            }

            ::root .tw-libswiper-textbox .tw-libswiper-item-tit:hover {
              color: ${this.titleHoverColor}
            }

            ::root .tw-libswiper-textbox .tw-libswiper-item-date {
              color: ${this.dateColor};
              font-size: ${this.dateFontSize};
            }
          `
        }
      }

      this.addStyle(style)
    },

    removeChildToSlide () {
      if (this.observer) {
        this.observer.disconnect()
      }

      const nums = this.needPseudoElement ? this.childNumber - 2 : this.childNumber

      for (let i = 0; i < nums; i++) {
        document.getElementById(this._uid + 'slide' + (this.needPseudoElement ? i + 2 : i + 1)).appendChild(this.$children[i].$el)
      }

      if (this.observer) {
        this.observer.observe(this.$refs.contentBox, { childList: true })
      }
    },

    slideChange (swiper) {
      this.activeIndex = swiper.activeIndex

      if (typeof this.slideFn === 'function') {
        this.slideFn(this.activeIndex, swiper)
        this.$emit('change', this.activeIndex)
      }
    },

    reachEnd (swiper) {
      if (typeof this.reachEndFn === 'function') {
        this.reachEndFn(this.activeIndex, swiper)
        this.$emit('reachEnd', this.activeIndex)
      }
    },

    init () {
      if (this.swiper) {
        try {
          this.swiper = this.swiper.destroy(true, true)
        } catch (e) {
          // noop
        }
      }

      const vm = this

      const config = {
        loop: this.loop && (window.$lib && window.$lib.env && window.$lib.env !== 'design'),
        direction: this.direction,
        mousewheel: this.wheelEnable,
        initialSlide: parseInt(this.initialSlide),
        slidesPerView: this.slidesPerView,
        speed: parseInt(this.speed),
        on: {
          slideChange () {
            vm.slideChange(this)
          },
          reachEnd () {
            vm.reachEnd(this)
          }
        }
      }

      if (this.autoplay && this.autoplayTime && this.autoplayTime !== '0') {
        config.autoplay = {
          delay: parseInt(this.autoplayTime || 0),
          disableOnInteraction: this.disableOnInteraction
        }
      }

      if (this.paginationEnable) {
        config.pagination = {
          el: `#swiper${this._uid} .swiper-pagination`,
          clickable: true
        }
      }

      if (this.buttonEnable && !this.buttonOUtEnable) {
        config.navigation = {
          nextEl: `#swiper-button-next${this._uid}`,
          prevEl: `#swiper-button-prev${this._uid}`
        }
      }

      if (this.buttonEnable && this.buttonOUtEnable) {
        config.navigation = {
          nextEl: `#swiper-button-next${this._uid}`,
          prevEl: `#swiper-button-prev${this._uid}`
        }
      }

      this.childNumber = this.$children.length

      if (config.initialSlide < 0) {
        config.initialSlide = 0
      } else if (config.initialSlide >= this.childNumber) {
        config.initialSlide = this.childNumber - 1
      }

      if (this.needPseudoElement) {
        config.initialSlide += 1
        this.childNumber += 2
      }

      this.activeIndex = config.initialSlide

      this.$nextTick(() => {
        if (this.type === 'content') {
          this.removeChildToSlide()
        }

        this.$nextTick(() => {
          this.swiper = new Swiper(`#swiper${this._uid}`, config)
        })
      })
    }
  },

  mounted () {
    window.ccc = this

    if (this.watchContent) {
      this.handleMutation(true)
    }

    this.init()
  },

  watch: {
    imageListFromApi() {
      this.init()
    },

    textListFromApi() {
      this.init()
    },

    swiperConfig: {
      deep: true,
      handler (val, old) {
        this.init()
      }
    },

    watchContent (val) {
      this.handleMutation(val)
    }
  }
}
</script>

<style lang="scss">
  @import './css/index.scss';
</style>
